home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 3 / bicalc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-05-29  |  12.9 KB  |  572 lines

  1.                         /* Alain Birtz, 8/12/85    */
  2. #include "gemdefs.h"
  3.  
  4. /************************************************************************/
  5.  
  6. #define WI_KIND        (MOVER|CLOSER|NAME)    /* can be moved, closed    */
  7.                         /* and title exist    */
  8. #define NO_WINDOW    (-1)
  9.  
  10. /************************************************************************/
  11.  
  12. extern int    gl_apid;
  13.  
  14. /************************************************************************/
  15.  
  16. int box[28][4];                    /* key            */
  17. int blank;                    /* screen state        */
  18. int dot;                    /* dot in float. point    */
  19. int oper=3;                    /* current operation    */
  20. long base=10L;                    /* 10=DECI, 16=HEXA    */
  21. long temp_base=0L;                /* used in octal,binary */
  22. long mem_val, scr_val;                /* arithmetic value    */
  23. long mem_div=1L, scr_div=1L;            /* used in float. point    */
  24. char key_symb[3][12]={
  25.     {'1','2','3','\275','4','5','6','+','7','8','9','-'},
  26.     {'0','!','\361','*','.','b','o','\366','%','&','|','='},
  27.     {'A','B','C','*','D','E','F','\366','0','&','|','='}
  28. };
  29. char hex_deci[][5]={"HEXA","DECI"};
  30. char chr[]=" ";                    /* to print one char    */
  31.  
  32.  
  33. int    menu_id ;                /* our menu id        */
  34.  
  35. int     phys_handle;                /* physical workstation    */
  36. int     handle;                    /* virtual workstation    */
  37. int    wi_handle;                /* window handle    */
  38. int    top_window;                /* handle of topped    */
  39.  
  40. int    xdesk=450,ydesk=50,hdesk=310,wdesk=150;
  41. int    xwork,ywork,hwork,wwork;        /* desktop , work areas    */
  42.  
  43. int    msgbuff[8];                /* event message buffer    */
  44. int    mx,my;                    /* mouse x and y pos.    */
  45. int    butdown;                /* button state        */
  46. int    d;                    /* dummy variable    */
  47.  
  48. int    contrl[12];                /* AES, VDI variable    */
  49. int    intin[128];
  50. int    ptsin[128];
  51. int    intout[128];
  52. int    ptsout[128];
  53.  
  54. int work_in[11];                /* Input GSX parameter    */
  55. int work_out[57];                /* Output GSX parameter    */
  56.  
  57. /************************************************************************/
  58.  
  59. open_vwork()                    /* open workstation    */
  60. {
  61. int i;
  62.     for(i=0;i<10;work_in[i++]=1);      
  63.         work_in[10]=2;
  64.     handle=phys_handle;
  65.     v_opnvwk(work_in,&handle,work_out);
  66. }
  67.  
  68. /************************************************************************/
  69.  
  70. open_window()                    /* open window        */
  71. {
  72.     wi_handle=wind_create(WI_KIND,xdesk,ydesk,wdesk,hdesk);
  73.     wind_set(wi_handle, WF_NAME," Calculator ",0,0);
  74.     wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk);
  75.     wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
  76. }
  77.  
  78. /************************************************************************/
  79.  
  80. main()
  81. {
  82.     appl_init();
  83.     phys_handle=graf_handle(&d,&d,&d,&d);
  84.     menu_id=menu_register(gl_apid,"  Calculator");
  85.  
  86.     wi_handle=NO_WINDOW;
  87.     butdown=1;
  88.  
  89.     multi();
  90. }
  91.  
  92. /************************************************************************/
  93.  
  94. multi()
  95. {
  96. int event, k;
  97.  
  98.     while (1)
  99.         {
  100.         event = evnt_multi(MU_MESAG | MU_BUTTON,
  101.                 1,1,butdown,0,0,0,0,0,0,0,0,0,0,
  102.                 msgbuff,0,0,&mx,&my,&d,&d,&d,&d);
  103.  
  104.         wind_update(1);
  105.         wind_get(wi_handle,WF_TOP,&top_window,&d,&d,&d);
  106.  
  107.         if (event & MU_MESAG)
  108.  
  109. /*..................................................begin switch........*/
  110. switch (msgbuff[0])
  111. {
  112.     case WM_NEWTOP:case WM_TOPPED:
  113.     if (msgbuff[3] == wi_handle)
  114.         {
  115.         wind_set(wi_handle,WF_TOP,0,0,0,0);
  116.         draw();
  117.         }
  118.     break;
  119.  
  120.     case AC_CLOSE:
  121.     if ((msgbuff[3] == menu_id)&&(wi_handle != NO_WINDOW))
  122.         {
  123.         v_clsvwk(handle);
  124.         wi_handle = NO_WINDOW;
  125.         }
  126.     break;
  127.  
  128.     case WM_CLOSED:
  129.     if (msgbuff[3] == wi_handle)
  130.         {
  131.         wind_close(wi_handle);
  132.         wind_delete(wi_handle);
  133.         v_clsvwk(handle);
  134.         wi_handle = NO_WINDOW;
  135.         graf_mouse(0,0);        /* arrow form        */  
  136.         }
  137.     break;
  138.  
  139.     case WM_MOVED:
  140.     if (msgbuff[3] == wi_handle)
  141.         {
  142.         wind_set(wi_handle,WF_CURRXYWH,msgbuff[4],msgbuff[5],msgbuff[6],            msgbuff[7]);
  143.         wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
  144.         draw();
  145.         }
  146.     break;
  147.  
  148.     case AC_OPEN:
  149.     if (msgbuff[4] == menu_id && wi_handle == NO_WINDOW)
  150.         {
  151.         open_vwork();
  152.             open_window();
  153.         draw();
  154.         }
  155.     break;
  156.  
  157. }
  158. /*....................................................end switch........*/
  159.  
  160.         if ((event & MU_BUTTON)&&(wi_handle == top_window))
  161.             if (butdown)
  162.                 {
  163.                 if ((k=key_numb())>-1)
  164.                     math(k);
  165.                 if (k==-2)
  166.                     author();    
  167.                  butdown=0;
  168.                 }
  169.             else
  170.                 butdown=1;
  171.  
  172.         wind_update(0);
  173.  
  174.     }                    /* end of while (1)    */
  175.  
  176. }
  177.        
  178. /************************************************************************/
  179.  
  180. author()
  181. {
  182. int i;
  183.  
  184.     v_gtext(handle,box[26][0]+5,box[26][3]-5," by A.Birtz");
  185.     for (i=0;i<15000;i++)
  186.         ;                /* timeout        */
  187.     v_gtext(handle,box[26][0]+5,box[26][3]-5,"           ");
  188. }
  189.  
  190. /************************************************************************/
  191.  
  192. one_key(no,style)                /* draw one key        */
  193. int no, style;
  194. {
  195. char *s;
  196.  
  197.     if (no<24)
  198.         {
  199.         chr[0]=key_symb[(no<12 ? 0:1+(base==16L))][no%12];
  200.         s=chr;
  201.         }
  202.     else
  203.         s=hex_deci[no-24];
  204.  
  205.     graf_mouse(256,0);            /* hide mouse        */
  206.     vsf_interior(handle,style);        /* white or black    */
  207.     vr_recfl(handle,box[no]);        /* clear and fill    */
  208.     rect(box[no]);                /* draw box and text    */
  209.     v_gtext(handle,box[no][0]+7+2*(no>23),box[no][3]-4,s);
  210.     graf_mouse(257,0);            /* show mouse        */
  211. }
  212.  
  213. /***********************************************************************/
  214.  
  215. reset_v()
  216. {
  217.     blank=1;
  218.     dot=0;
  219.     scr_val=mem_val=0L;
  220.     scr_div=mem_div=1L;
  221. }
  222.  
  223. /***********************************************************************/
  224.  
  225. plus()
  226. {
  227. long max_div;
  228.  
  229.     if (scr_div>1L || mem_div>1L)
  230.         {
  231.         max_div=(scr_div>mem_div ? scr_div:mem_div);
  232.         scr_val=max_div/mem_div*mem_val + max_div/scr_div*scr_val;
  233.         scr_div=max_div;
  234.         }
  235.     else
  236.         scr_val += mem_val;
  237. }
  238.  
  239. /***********************************************************************/
  240.  
  241. minus()
  242. {
  243. long max_div;
  244.  
  245.     if (scr_div>1L || mem_div>1L)
  246.         {
  247.         max_div=(scr_div>mem_div ? scr_div:mem_div);
  248.         scr_val=max_div/mem_div*mem_val - max_div/scr_div*scr_val;
  249.         scr_div=max_div;
  250.         }
  251.     else
  252.         scr_val=mem_val-scr_val;
  253. }
  254.  
  255. /***********************************************************************/
  256.  
  257. product()
  258. {
  259.     scr_val *= mem_val;
  260.     scr_div *= mem_div;
  261.     while (scr_div>100L)
  262.         {
  263.         scr_val /= 10L;
  264.         scr_div /= 10L;
  265.         }
  266. }
  267.  
  268. /***********************************************************************/
  269.  
  270. quotient()
  271. {
  272. long work;
  273.  
  274.     if (!scr_div)                /* division by zero    */
  275.         return;
  276.  
  277.     if (scr_div>1L || mem_div>1L)
  278.         {
  279.         work=100L;
  280.         scr_val=work/mem_div*mem_val*scr_div/scr_val;
  281.         scr_div=100L;
  282.         }
  283.     else
  284.         scr_val=mem_val/scr_val;
  285. }
  286.  
  287. /***********************************************************************/
  288.  
  289. math(k)
  290. int k;
  291. {
  292. int i;
  293. long fact;
  294.  
  295.     blank=0;
  296.     
  297.     if (k!=-1 && k<21 && k%4!=3)        /* digit (DECI or HEXA)    */
  298.         if (base==16L || (k<13 && (!dot || scr_div<100L)))
  299.         {
  300.         scr_val *= base;
  301.         scr_val += (long) ((3*(k/4) + k%4 + 1)%(base==10L ? 10:16));
  302.         if (dot)
  303.             scr_div *= 10L;
  304.         }
  305.  
  306.     switch(k)
  307.     {
  308.     case 3:reset_v();break;            /* clear        */            case 7:case 11:case 15:case 19:case 21:case 22:
  309.                         /* + - * / & |        */
  310.         mem_div=scr_div;scr_div=1L;
  311.         mem_val=scr_val;scr_val=0L;
  312.         oper=k;blank=1;dot=0;break;
  313.     case 13:                /* factorial        */
  314.         if (base==10L && scr_val>-1L && scr_val<16L)
  315.             {
  316.             i=1; fact=1L;
  317.             while (i< (int) scr_val)
  318.                 fact *= (long) ++i;
  319.             scr_val=fact;
  320.             }
  321.         break;
  322.     case 14:if (base==10L)            /* sign change        */
  323.             scr_val= -scr_val;
  324.         break;
  325.     case 16:if (base==10L)            /* set float point dot    */
  326.             dot=1;
  327.         break;
  328.     case 17:case 18:            /* binary and octal    */
  329.         if (!dot && base==10L)
  330.             {
  331.             temp_base=(k==17 ? 2L:8L);
  332.             if (k==17)        /* first 8 bits only    */
  333.                 scr_val &= 0xff;
  334.             }
  335.         break;
  336.     case 20:if (base==10L)            /* per cent (%)        */
  337.             {
  338.             while (mem_div<100L)
  339.                 {
  340.                 mem_div *= 10L;    /* convert in float.    */
  341.                 mem_val *= 10L;
  342.                 }
  343.             product();scr_val /= 100L;
  344.             }
  345.         break;
  346.     case 23:switch(oper)            /* equal (=)        */
  347.         {
  348.         case  7:plus();break;
  349.         case 11:minus();break;
  350.         case 15:product();break;
  351.         case 19:quotient();break;
  352.         case 21:if (!dot)        /* 'and' operator    */
  353.                 scr_val &= mem_val;
  354.             break;
  355.         case 22:            /* 'or' operator    */
  356.             if (!dot)
  357.                 scr_val |= mem_val;
  358.             break;
  359.         default:break;
  360.         }
  361.         break;
  362.     case 24:case 25:            /* HEXA or DECI        */
  363.         base=(k==24 ? 16L:10L);
  364.         one_key(24,(k==24));one_key(25,(k==25));
  365.         for(i=12;i<21;i++)
  366.             if (i%4!=3)        /* draw new key        */
  367.                 one_key(i,0);
  368.         if (dot)
  369.             reset_v();
  370.         if (mem_div>1L)
  371.             {
  372.             mem_val=0L;
  373.             mem_div=1L;
  374.             }
  375.         break;
  376.     default:
  377.         break;
  378.     }
  379.  
  380.     display();
  381. }
  382.  
  383. /**************************************************************************/
  384.  
  385. rect(pos)                             /* pos[0],pos[1] left upper corner  */  
  386. int pos[];                            /* pos[2],pos[3] right lower corner */                        
  387. {
  388. int pxyarray[12];
  389.  
  390.    pxyarray[0] = pos[0];
  391.    pxyarray[1] = pos[1];
  392.    pxyarray[2] = pos[2];
  393.    pxyarray[3] = pos[1];
  394.    pxyarray[4] = pos[2];
  395.    pxyarray[5] = pos[3];
  396.    pxyarray[6] = pos[0];
  397.    pxyarray[7] = pos[3];
  398.    pxyarray[8] = pos[0];
  399.    pxyarray[9] = pos[1];
  400.    pxyarray[10] = pos[2];              /* one more for corner end */
  401.    pxyarray[11] = pos[1]; 
  402.  
  403.    v_pline(handle,6,pxyarray);
  404. }
  405.  
  406. /***********************************************************************/
  407.  
  408. draw()
  409. {
  410. int i, j;
  411. char chr[2];
  412.  
  413.     for(j=0;j<6;j++)            /* 6 key row        */
  414.         for(i=0;i<4;i++)        /* 4 column        */
  415.         {
  416.            box[i+4*j][0]=xwork+20+30*i;    /* left upper x        */
  417.         box[i+4*j][2]=box[i+4*j][0]+20;    /* right lower x    */
  418.            box[i+4*j][1]=ywork+100+30*j;    /* left upper y        */
  419.            box[i+4*j][3]=box[i+4*j][1]+20;    /* right lower y    */          
  420.         }
  421.     for(i=0;i<2;i++)            /* HEXA and DECI box    */
  422.     {
  423.     box[i+24][0]=xwork+20+60*i;
  424.     box[i+24][2]=box[i+24][0]+50;
  425.     box[i+24][1]=ywork+70;
  426.     box[i+4*j][3]=box[i+24][1]+20;
  427.     }
  428.         
  429.     box[26][0]=xwork+20;            /* show box        */
  430.     box[26][2]=xwork+130;
  431.     box[26][1]=ywork+20;
  432.     box[26][3]=ywork+50;
  433.  
  434.     box[27][0]=xwork;            /* calculator box    */
  435.     box[27][1]=ywork;
  436.     box[27][2]=xwork+wwork;
  437.     box[27][3]=ywork+hwork;
  438.  
  439.  
  440.     vsl_width(handle,2);            /* line width        */
  441.     graf_mouse(256,0);            /* hide mouse        */  
  442.  
  443.     vsf_interior(handle,2);            /* style 2        */
  444.     vsf_style(handle,6);            /* index 6        */
  445.     vr_recfl(handle,box[27]);        /* fill window        */
  446.  
  447.     graf_mouse(257,0);            /* show mouse        */
  448.  
  449.     for(i=0;i<25;i++)            /* draw key box        */ 
  450.         one_key(i,0);            /* with white fill    */    
  451.     one_key(25,1);                /* DECI active        */
  452.  
  453.     graf_mouse(256,0);            /* hide mouse        */  
  454.  
  455.     vsf_interior(handle,0);            /* white        */     
  456.         vr_recfl(handle,box[26]);        /* clear        */
  457.     rect(box[26]);                /* draw show box    */
  458.     for(i=0;i<4;i++)            /* reduce size        */
  459.         box[26][i] += 3*(1-2*(i>1));
  460.     rect(box[26]);                /* interior box        */
  461.  
  462.     graf_mouse(3,0);            /* extented finger    */
  463.     graf_mouse(257,0);            /* show mouse        */
  464. }
  465.  
  466. /***********************************************************************/
  467.  
  468. key_numb()    /* return the clicked key number or -1    if outside    */
  469. {
  470. int mx_k, my_k;
  471. int r, c;
  472.  
  473.     if (mx>box[27][2]-3 && my>box[27][3]-3)
  474.         return (-2);            /* mysterious box    */
  475.  
  476.     mx_k = mx - (xwork + 20);        /* coord relative to    */
  477.     my_k = my - (ywork + 70);        /* the keypad block    */
  478.  
  479.     if (mx_k<0 || mx_k>110 || my_k<0 || my_k>200)
  480.         return (-1);            /* outside the keypad    */
  481.  
  482.     r = my_k / 10;                /* 10 pixels row    */
  483.     c = mx_k / 10;                /* 10 pixels column    */
  484.  
  485.     if (r % 3 == 2)
  486.         return (-1);            /* between two row    */
  487.  
  488.     r /= 3;                    /* now r is key row    */ 
  489.                         /* number        */
  490.     if (r == 0)
  491.         if (c == 5)
  492.             return (-1);        /* between HEX and DECI    */
  493.         else
  494.             return (24 + c / 6);    /* HEXA or DECI value    */
  495.  
  496.     if (c % 3 == 2)
  497.         return (-1);            /* between column    */
  498.  
  499.     c /= 3;                    /* now c is column key    */
  500.                         /* number        */
  501.     return (c + 4 * (r - 1));        /* other key        */
  502. }
  503.  
  504. /***********************************************************************/    
  505. display()
  506. {
  507. int neg, s_index, l_div, i;
  508. long same, value, work_base, r;
  509. char s[12];
  510.  
  511.     for(i=0;i<12;i++)            /* white space        */
  512.         s[i]=' ';
  513.     s[i]='\0';
  514.  
  515.     if (blank)                /* nothing to print    */            {
  516.         v_gtext(handle,box[26][0]+5,box[26][3]-5,s);
  517.         return;
  518.         }
  519.  
  520.     neg=0;
  521.     s_index=11;
  522.     same=value=scr_val;
  523.     l_div= (scr_div>1L)+(scr_div>10L);
  524.  
  525.     work_base=(!temp_base ? base:temp_base);
  526.  
  527.     if (value==0L)                /* if zero        */
  528.         {
  529.         if (l_div)
  530.             {
  531.             for(i=0;i<l_div;i++)
  532.                 s[s_index--]='0';
  533.             s[s_index--]='.';
  534.             }
  535.         else
  536.             if (dot)
  537.                 s[s_index--]='.';
  538.             else
  539.                 s[s_index--]='0';
  540.         }
  541.  
  542.     if (value<0L)                /* if negative        */
  543.         {
  544.         same = value = -value;         /* make positive    */
  545.         neg=1;                /* set neg flag        */
  546.         }
  547.  
  548.     while (value>0L)
  549.         {
  550.         if ((dot || scr_div>1L) && s_index==11-l_div)
  551.             s[s_index--]='.';
  552.         r = value;            /* % seem don't work    */
  553.         value /= work_base;        /* with long integer    */
  554.         r -= work_base*value;        /* on DRI C        */
  555.         s[s_index--]= (base==16L && r>9L ? 'A'-10:'0') + (int) r;
  556.         }
  557.  
  558.     if (same && scr_div>same)
  559.         {                /* header . and 0    */
  560.         i=l_div+s_index-11;
  561.         while(i--)
  562.             s[s_index--]='0';
  563.         s[s_index--]='.';
  564.         }
  565.  
  566.     temp_base=0L;
  567.  
  568.     if (neg==1)                /* negative need sign -    */
  569.         s[s_index]='-';
  570.  
  571.     v_gtext(handle,box[26][0]+5,box[26][3]-5,s);
  572. }əəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəəə